#pragma once

#include <AVUILocalValueEntry.h>

namespace AVUI
{

/// <summary>Provides enumeration support for the local values of any dependency properties that exist on a <see cref="T:System.Windows.DependencyObject" />.</summary>
class LocalValueEnumerator : public Object, public IEnumerator
{
public:
    DECLARE_ELEMENT(LocalValueEnumerator, Object);

    /// <summary>Advances the enumerator to the next element of the collection.</summary>
    /// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns>
    bool MoveNext()
    {
        m_index++;
        return (m_index < get_Count());
    }

    /// <summary>Sets the enumerator to its initial position, which is before the first element in the collection.</summary>
    /// <returns />
    void Reset()
    {
        m_index = -1;
    }

    /// <summary>Gets whether the enumerator is currently in a valid state. </summary>
    /// <returns>true if Current is readable, false if current is invalid.</returns>
    bool IsInvalid()
    {
        return m_index == -1 || m_index >= get_Count();
    }


    /// <summary>Gets the number of items that are represented in the collection. </summary>
    /// <returns>The number of items in the collection.</returns>
    int get_Count() { return m_count; }

    /// <summary>Gets the current element in the collection.</summary>
    /// <returns>The current <see cref="T:System.Windows.LocalValueEntry" /> in the collection.</returns>
    LocalValueEntry get_CurrentValue()
    {
        if (m_index == -1)
        {
            LibraryThrowException(object_allocate<ArgumentNullException>("Local value enumeration reset."));
        }
        if (m_index >= get_Count())
        {
            LibraryThrowException(object_allocate<ArgumentNullException>("Local value enumeration out of bounds."));
        }
        return m_pSnapshot[m_index];
    }
 


    /// <summary>Gets the current element in the collection.</summary>
    /// <returns>The current <see cref="T:System.Windows.LocalValueEntry" /> in the collection.</returns>
    ObjectPtr IEnumerator::get_Current()
    {
        return BoxValue(LocalValueEnumerator::get_CurrentValue());
    }

    virtual Object* get_Object() { return Object::get_Object(); }

public:
    LocalValueEnumerator(TArrayPtr<LocalValueEntry> pSnapshot, int count) : m_pSnapshot(pSnapshot), m_index(-1), m_count(count) { }

private:
    int m_index;
    TArrayPtr<LocalValueEntry> m_pSnapshot;
    int m_count;
};


}

